package com.frank.oj.controller.oj;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.frank.model.entity.common.Announcement;
import com.frank.oj.annotation.AnonApi;
import com.frank.oj.common.result.CommonResult;
import com.frank.oj.model.dto.ContestPrintDTO;
import com.frank.oj.model.dto.ContestRankDTO;
import com.frank.oj.model.dto.RegisterContestDTO;
import com.frank.oj.model.dto.UserReadContestAnnouncementDTO;
import com.frank.oj.model.vo.*;
import com.frank.oj.service.oj.ContestScoreBoardService;
import com.frank.oj.service.oj.ContestService;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author frank
 * @Date 2024/3/23
 */
@RestController
@RequestMapping("/api")
public class ContestController {

    @Resource
    private ContestService contestService;
    @Resource
    private ContestScoreBoardService contestScoreBoardService;

    /**
     * 获取比赛列表
     *
     * @param limit       单页数
     * @param currentPage 页
     * @param status      比赛状态
     * @param type        比赛类型
     * @param keyword     搜索词
     * @return 返回结果
     */
    @GetMapping("/get-contest-list")
    @AnonApi
    public CommonResult<IPage<ContestVO>> getContestList(@RequestParam(value = "limit", required = false) Integer limit,
                                                         @RequestParam(value = "currentPage", required = false) Integer currentPage,
                                                         @RequestParam(value = "status", required = false) Integer status,
                                                         @RequestParam(value = "type", required = false) Integer type,
                                                         @RequestParam(value = "keyword", required = false) String keyword) {
        return contestService.getContestList(limit, currentPage, status, type, keyword);
    }

    /**
     * 获取比赛详情
     *
     * @param cid 比赛id
     * @return 返回结果
     */
    @GetMapping("/get-contest-info")
    @RequiresAuthentication
    public CommonResult<ContestVO> getContestInfo(@RequestParam(value = "cid", required = true) Long cid) {

        return contestService.getContestInfo(cid);
    }

    /**
     * 获取比赛成员
     */
    @GetMapping("/get-contest-member")
    @RequiresAuthentication
    public CommonResult<List<RegisterVO>> getContestMember(@RequestParam(value = "cid", required = true) Long cid) {
        return contestService.getContestMember(cid);
    }

    /**
     * 修改比赛人员状态
     */
    @PutMapping("update-contest-member")
    @RequiresAuthentication
    public CommonResult<Void> updateContestMemberStatus(@RequestParam(value = "contestID", required = true) Long contestID,
                                                      @RequestParam(value = "username", required = true) String username,
                                                      @RequestParam(value = "auth", required = true) Integer auth) {
        return contestService.updateContestMemberStatus(contestID, username, auth);
    }
    /**
     * 获取比赛题目
     */
    @GetMapping("/get-contest-problem")
    public CommonResult<List<ContestProblemVO>> getContestProblem(@RequestParam(value = "cid", required = true) Long cid,
                                                                  @RequestParam(value = "containsEnd", defaultValue = "false") Boolean containsEnd) {

        return contestService.getContestProblem(cid, containsEnd);
    }

    /**
     * 获取比赛题目详情
     */
    @GetMapping("/get-contest-problem-details")
    @RequiresAuthentication
    public CommonResult<ProblemInfoVO> getContestProblemDetails(@RequestParam(value = "cid", required = true) Long cid,
                                                                @RequestParam(value = "displayId", required = true) String displayId,
                                                                @RequestParam(value = "containsEnd", defaultValue = "false") Boolean containsEnd) {

        return contestService.getContestProblemDetails(cid, displayId, containsEnd);
    }

    /**
     * 获取比赛提交信息
     */
    @GetMapping("/contest-submissions")
    @RequiresAuthentication
    public CommonResult<IPage<JudgeVO>> getContestSubmissionList(@RequestParam(value = "limit", required = false) Integer limit,
                                                                 @RequestParam(value = "currentPage", required = false) Integer currentPage,
                                                                 @RequestParam(value = "onlyMine", required = false) Boolean onlyMine,
                                                                 @RequestParam(value = "problemID", required = false) String displayId,
                                                                 @RequestParam(value = "status", required = false) Integer searchStatus,
                                                                 @RequestParam(value = "username", required = false) String searchUsername,
                                                                 @RequestParam(value = "contestID", required = true) Long searchCid,
                                                                 @RequestParam(value = "beforeContestSubmit", required = true) Boolean beforeContestSubmit,
                                                                 @RequestParam(value = "completeProblemID", defaultValue = "false") Boolean completeProblemID,
                                                                 @RequestParam(value = "containsEnd", defaultValue = "false") Boolean containsEnd) {

        return contestService.getContestSubmissionList(
                limit,
                currentPage,
                onlyMine,
                displayId,
                searchStatus,
                searchUsername,
                searchCid,
                beforeContestSubmit,
                completeProblemID,
                containsEnd);
    }


    @PostMapping("/get-contest-rank")
    @RequiresAuthentication
    public CommonResult<IPage> getCompetitionRank(@RequestBody ContestRankDTO contestRankDTO) {
        return contestService.getContestRank(contestRankDTO);
    }

    /**
     * 获得比赛的通知列表
     */
    @GetMapping("/get-contest-announcement")
    @RequiresAuthentication
    public CommonResult<IPage<AnnouncementVO>> getContestAnnouncement(@RequestParam(value = "cid", required = true) Long cid,
                                                                      @RequestParam(value = "limit", required = false) Integer limit,
                                                                      @RequestParam(value = "currentPage", required = false) Integer currentPage) {

        return contestService.getContestAnnouncement(cid, limit, currentPage);
    }


    /**
     * 根据前端传过来的比赛id以及已阅读的公告提示id列表，排除后获取未阅读的公告
     */
    @PostMapping("/get-contest-not-read-announcement")
    @RequiresAuthentication
    public CommonResult<List<Announcement>> getContestUserNotReadAnnouncement(@RequestBody UserReadContestAnnouncementDTO userReadContestAnnouncementDto) {
        return contestService.getContestUserNotReadAnnouncement(userReadContestAnnouncementDto);
    }

    /**
     * 提交打印文本
     */
    @PostMapping("/submit-print-text")
    @RequiresAuthentication
    public CommonResult<Void> submitPrintText(@RequestBody ContestPrintDTO contestPrintDto) {

        return contestService.submitPrintText(contestPrintDto);
    }

    /**
     * 获取比赛访问权限
     */
    @GetMapping("/get-contest-access")
    @RequiresAuthentication
    public CommonResult<AccessVO> getContestAccess(@RequestParam(value = "cid", required = true) Long cid) {

        return contestService.getContestAccess(cid);
    }

    /**
     * 比赛注册
     */
    @PostMapping("/register-contest")
    @RequiresAuthentication
    public CommonResult<Void> toRegisterContest(@RequestBody RegisterContestDTO registerContestDto) {
        return contestService.toRegisterContest(registerContestDto);
    }

    /**
     * 赛外比赛西信息及题目信息
     */
    @GetMapping("/get-contest-outsize-info")
    public CommonResult<ContestOutsideInfoVO> getContestOutsideInfo(@RequestParam(value = "cid", required = true) Long cid) {
        return contestScoreBoardService.getContestOutsideInfo(cid);
    }

    /**
     * 获取比赛外榜
     */
    @PostMapping("/get-contest-outside-scoreboard")
    @RequiresAuthentication
    public CommonResult<IPage> getContestOutsideScoreboard(@RequestBody ContestRankDTO contestRankDto) {
        return contestScoreBoardService.getContestOutsideScoreboard(contestRankDto);
    }
}
